﻿using MediatR;
using SmartCity.EventHandle.API.Write.Application.Commands;
using SmartCity.EventHandle.Domain;
using SmartCity.EventHandle.Errorcode;
using SmartCity.EventHandle.Infrastructure.Commons;
using SmartCity.EventHandle.Infrastructure.Extensions;
using SmartCity.EventHandle.Infrastructure.Interfraces;
using Yitter.IdGenerator;

namespace SmartCity.EventHandle.API.Write.Application.CommandHandlers
{
    /// <summary>
    /// 应用添加命令处理
    /// </summary>
    public class AppCreateCommandHandler:IRequestHandler<AppCreateCommand,ApiResult<int>>
    {
        /// <summary>
        /// 实力仓储
        /// </summary>
        private readonly IBaseRepository<WF_Instance> instanceRep;
        /// <summary>
        /// 流程流转仓储
        /// </summary>
        private readonly IBaseRepository<WF_Record> recordRep;
        private readonly ILogger<AppCreateCommandHandler> logger;
        /// <summary>
        /// 流程设置仓储
        /// </summary>
        private readonly IBaseRepository<WF_Setting> settingRep;

        public AppCreateCommandHandler(
            IBaseRepository<WF_Instance> instanceRep,
            IBaseRepository<WF_Record> recordRep, 
            IBaseRepository<WF_Setting> settingRep,
            ILogger<AppCreateCommandHandler> logger)
        {
            this.instanceRep = instanceRep;
            this.recordRep = recordRep;
            this.logger = logger;
            this.settingRep = settingRep;
        }
        /// <summary>
        /// 处理
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns>返回添加任务</returns>

        public async Task<ApiResult<int>> Handle(AppCreateCommand request, CancellationToken cancellationToken)
        {
            ApiResult<int> result = new ApiResult<int>();
            result.code = ApiEnum.AddSuccess;
            result.message = ApiEnum.AddSuccess.GetDescription();
            //事务
            using (var tran = settingRep.DB.Database.BeginTransaction())
            {
                try
                {
                    DateTime now = DateTime.Now;
                    #region 实例表添加
                    WF_Instance instance = new WF_Instance();
                    instance.InstanceId = YitIdHelper.NextId().ToString();
                    instance.IndustryId = request.IndustryId;
                    instance.IndustryName = request.IndustryName;
                    instance.TypeNo = request.TypeNo;
                    instance.TypeName = request.TypeName;
                    instance.FormNo = request.FormNo;
                    instance.FormName = request.FormName;
                    instance.FormContent = request.FormContent;

                    instance.FlowState = (int)FlowStatus.Submit;
                    instance.FlowStateName = FlowStatus.Submit.GetDescription();

                    instance.StartId = request.UserId;
                    instance.StartName = request.UserNickName;

                    //查询流程设置
                    var settings = settingRep.GetAll().Where(x => x.FormNo == request.FormNo && !x.IsDeleted).OrderBy(x=>x.NodeNo).ToList();
                    if (settings.Count < 2)
                    {
                        throw new Exception("流程设置数据不对,请联系管理员");
                    }

                    instance.CurrentNodeNo = settings[0].NodeNo;
                    instance.CurrentNodeName = settings[0].NodeName;
                    instance.CurrentOperatorId = request.UserId;
                    instance.CurrentOperatorName = request.UserNickName;

                    instance.NextNodeNo = settings[0].NodeNo;
                    instance.NextNodeName = settings[0].NodeName;
                    instance.NextOperatorId = request.UserId;
                    instance.NextOperatorName = request.UserNickName;

                    instance.CreateTime = now;

                    await instanceRep.AddAsync(instance);
                    #endregion

                    WF_Record record = new WF_Record();
                    record.RecordId = YitIdHelper.NextId().ToString();
                    record.InstanceId = instance.InstanceId;

                    record.NodeNo = instance.CurrentNodeNo;
                    record.NodeName = instance.CurrentNodeName;
                    record.OperatorId = instance.CurrentOperatorId;
                    record.OperatorName = instance.CurrentOperatorName;
                    record.OperatorOpinion = "";

                    record.ApproveStatus = (int)ApproveStatus.Submit;
                    record.ApproveStatusName = ApproveStatus.Submit.GetDescription();

                    record.CreateTime = now;

                    await recordRep.AddAsync(record);
                }
                catch (Exception)
                {

                    throw;
                }
            }
            return await Task.FromResult(result);
        }
    }
}
